package com.spsoft.vatoutinv.service.vmsrealregionalconfig.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spsoft.core.enums.ResponseEnum;
import com.spsoft.core.exception.BusinessException;
import com.spsoft.core.model.Result;
import com.spsoft.core.utils.BeanUtils;
import com.spsoft.vatoutinv.constants.CommonConstant;
import com.spsoft.vatoutinv.entity.vmsrealregionalconfig.VmsRealRegionalConfig;
import com.spsoft.vatoutinv.enums.CommonEnum;
import com.spsoft.vatoutinv.mapper.VmsRealRegionalConfigMapper;
import com.spsoft.vatoutinv.model.dto.vmsrealregionalconfig.VmsRealRegionalConfigAddDTO;
import com.spsoft.vatoutinv.model.dto.vmsrealregionalconfig.VmsRealRegionalConfigDTO;
import com.spsoft.vatoutinv.model.dto.vmsrealregionalconfig.VmsRealRegionalConfigUpdateDTO;
import com.spsoft.vatoutinv.model.vo.vmsrealregionalconfig.VmsRealRegionalConfigListVO;
import com.spsoft.vatoutinv.model.vo.vmsrealregionalconfig.VmsRealRegionalConfigPageVO;
import com.spsoft.vatoutinv.model.vo.vmsrealregionalconfig.VmsRealRegionalConfigVO;
import com.spsoft.vatoutinv.service.vmsrealregionalconfig.VmsRealRegionalConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author wangy
 * @Desc (VmsRealRegionalConfig)表服务实现类
 * @Date 2024-03-22 14:44:01
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class VmsRealRegionalConfigServiceImpl extends ServiceImpl<VmsRealRegionalConfigMapper, VmsRealRegionalConfig> implements VmsRealRegionalConfigService {

    @Override
    public Result<IPage<VmsRealRegionalConfigPageVO>> queryByPage(VmsRealRegionalConfigDTO param) {
        Integer pageNo = param.getPageNo();
        Integer pageSize = param.getPageSize();
        Page<VmsRealRegionalConfig> page = this.page(new Page<>(pageNo, pageSize),
                new LambdaQueryWrapper<VmsRealRegionalConfig>()
                        .eq(VmsRealRegionalConfig::getRegionLevel, CommonEnum.REGION_LEVEL_1.getKey())
                        .orderByDesc(VmsRealRegionalConfig::getId)
        );
        HashMap<Long, List<VmsRealRegionalConfig>> map = new HashMap<>();
        List<VmsRealRegionalConfig> list = list(new LambdaQueryWrapper<VmsRealRegionalConfig>()
                .eq(VmsRealRegionalConfig::getRegionLevel, CommonEnum.REGION_LEVEL_2.getKey())
        );
        for (VmsRealRegionalConfig vmsRealRegionalConfig : list) {
            List<VmsRealRegionalConfig> vmsRealRegionalConfigs = map.computeIfAbsent(vmsRealRegionalConfig.getParentId(), k -> new ArrayList<>());
            vmsRealRegionalConfigs.add(vmsRealRegionalConfig);
        }
        IPage<VmsRealRegionalConfigPageVO> iPage = page.convert(item -> {
            VmsRealRegionalConfigPageVO vo = new VmsRealRegionalConfigPageVO();
            vo.setId(item.getId());
            vo.setName(item.getName());
            vo.setParentId(item.getParentId());
            vo.setRegionLevel(item.getRegionLevel());
            vo.setStatus(item.getStatus());
            vo.setChildren(map.get(item.getId()));
            return vo;
        });
        return Result.OK(iPage);
    }

    @Override
    public Result<VmsRealRegionalConfigVO> queryById(Long id) {
        VmsRealRegionalConfig byId = getById(id);
        VmsRealRegionalConfigVO vo = new VmsRealRegionalConfigVO();
        BeanUtils.copyBeanProp(vo, byId);
        return Result.OK(vo);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result insert(VmsRealRegionalConfigAddDTO vmsRealRegionalConfigAddDTO) {
        checkParam(vmsRealRegionalConfigAddDTO);
        if (ObjectUtil.isNotEmpty(vmsRealRegionalConfigAddDTO.getId())) {
            VmsRealRegionalConfigUpdateDTO updateDTO = new VmsRealRegionalConfigUpdateDTO();
            BeanUtils.copyBeanProp(updateDTO, vmsRealRegionalConfigAddDTO);
            return update(updateDTO);
        }
        VmsRealRegionalConfig entity = new VmsRealRegionalConfig();
        BeanUtils.copyBeanProp(entity, vmsRealRegionalConfigAddDTO);
        save(entity);
        return Result.OK(entity.getId());
    }

    private void checkParam(VmsRealRegionalConfigAddDTO vmsRealRegionalConfigAddDTO) {
        // 名称最大长度20位
        if (vmsRealRegionalConfigAddDTO.getName().length() > 20) {
            throw new BusinessException(ResponseEnum.REAL_REGION_CONFIG_ERROR_04);
        }
        // 如果是省级区域 必须以省、自治区、特别行政区、北京市、天津市、上海市、重庆市任意一个关键词结尾。 例如：广东省、广西壮族自治区、香港特别行政区、北京市、天津市、上海市、重庆市
        if (CommonEnum.REGION_LEVEL_1.getKey().equals(vmsRealRegionalConfigAddDTO.getRegionLevel())) {
            String name = vmsRealRegionalConfigAddDTO.getName();
            if (!name.endsWith("省") && !name.endsWith("自治区") && !name.endsWith("特别行政区") && !"北京市".equals(name) && !"天津市".equals(name) && !"上海市".equals(name) && !"重庆市".equals(name)) {
                throw new BusinessException(ResponseEnum.REAL_REGION_CONFIG_ERROR_02);
            }
        }
        // 如果是市级区域 必须以市、盟、自治州、地区、区任意一个关键词结尾
        if (CommonEnum.REGION_LEVEL_2.getKey().equals(vmsRealRegionalConfigAddDTO.getRegionLevel())) {
            String name = vmsRealRegionalConfigAddDTO.getName();
            if (!name.endsWith("市") && !name.endsWith("盟") && !name.endsWith("自治州") && !name.endsWith("地区") && !name.endsWith("区")) {
                throw new BusinessException(ResponseEnum.REAL_REGION_CONFIG_ERROR_03);
            }
        }
        // 校验名称是否重复
        int count = count(new LambdaQueryWrapper<VmsRealRegionalConfig>()
                .eq(VmsRealRegionalConfig::getName, vmsRealRegionalConfigAddDTO.getName()));
        if (count > 0) {
            throw new BusinessException(ResponseEnum.ABNORMAL_DUPLICATE_NAME);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result update(VmsRealRegionalConfigUpdateDTO vmsRealRegionalConfigUpdateDTO) {
        VmsRealRegionalConfig entity = new VmsRealRegionalConfig();
        BeanUtils.copyBeanProp(entity, vmsRealRegionalConfigUpdateDTO);
        if (CommonEnum.REGION_LEVEL_1.getKey().equals(entity.getRegionLevel())) {
            entity.setParentId(null);
        }
        int result = this.baseMapper.updateEntity(entity);
        return result > 0 ? Result.OK() : Result.ERROR("修改失败");
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Long> deleteById(Long id) {
        remove(new LambdaQueryWrapper<VmsRealRegionalConfig>()
                .eq(VmsRealRegionalConfig::getParentId, id)
        );
        removeById(id);
        return Result.OK(id);
    }

    @Override
    public Result<List<VmsRealRegionalConfigVO>> getProvince() {
        List<VmsRealRegionalConfig> list = list(new LambdaQueryWrapper<VmsRealRegionalConfig>()
                .eq(VmsRealRegionalConfig::getRegionLevel, CommonEnum.REGION_LEVEL_1.getKey())
                .eq(VmsRealRegionalConfig::getStatus, CommonConstant.STR_Y)
                .orderByDesc(VmsRealRegionalConfig::getId)
        );
        List<VmsRealRegionalConfigVO> collect = list.stream().map(item -> {
            VmsRealRegionalConfigVO vo = new VmsRealRegionalConfigVO();
            BeanUtils.copyBeanProp(vo, item);
            return vo;
        }).collect(Collectors.toList());
        return Result.OK(collect);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> updateStatus(VmsRealRegionalConfigDTO param) {
        // 获取数据库内信息
        VmsRealRegionalConfig byId = getById(param.getId());
        if (byId == null) {
            return Result.ERROR(ResponseEnum.ERROR);
        }
        // 创建修改List
        ArrayList<Long> vmsRealRegionalConfigs = new ArrayList<>();
        vmsRealRegionalConfigs.add(byId.getId());
        String status = CommonConstant.STR_Y.equals(byId.getStatus()) ? CommonConstant.STR_N : CommonConstant.STR_Y;
        // 如果是省级区域，下级区域也要修改
        if (CommonConstant.STR_1.equals(byId.getRegionLevel())) {
            List<VmsRealRegionalConfig> list = list(new LambdaQueryWrapper<VmsRealRegionalConfig>()
                    .eq(VmsRealRegionalConfig::getParentId, byId.getId())
            );
            for (VmsRealRegionalConfig vmsRealRegionalConfig : list) {
                vmsRealRegionalConfigs.add(vmsRealRegionalConfig.getId());
            }
        }
        int result = this.baseMapper.updateStatus(vmsRealRegionalConfigs, status);

        return result == vmsRealRegionalConfigs.size() ? Result.OK() : Result.ERROR(ResponseEnum.REAL_REGION_CONFIG_ERROR_01);
    }

    @Override
    public Result<List<VmsRealRegionalConfigListVO>> getList() {
        List<VmsRealRegionalConfig> list = list(new LambdaQueryWrapper<VmsRealRegionalConfig>()
                .eq(VmsRealRegionalConfig::getRegionLevel, CommonEnum.REGION_LEVEL_1.getKey())
                .eq(VmsRealRegionalConfig::getStatus, CommonConstant.STR_Y)
                .orderByDesc(VmsRealRegionalConfig::getId)
        );

        List<VmsRealRegionalConfig> list1 = list(new LambdaQueryWrapper<VmsRealRegionalConfig>()
                .eq(VmsRealRegionalConfig::getRegionLevel, CommonEnum.REGION_LEVEL_2.getKey())
                .eq(VmsRealRegionalConfig::getStatus, CommonConstant.STR_Y)
        );
        // 子节点的map
        HashMap<Long, List<VmsRealRegionalConfigListVO>> map = new HashMap<>();
        for (VmsRealRegionalConfig vmsRealRegionalConfig : list1) {
            List<VmsRealRegionalConfigListVO> vmsRealRegionalConfigs = map.computeIfAbsent(vmsRealRegionalConfig.getParentId(), k -> new ArrayList<>());
            VmsRealRegionalConfigListVO vo = new VmsRealRegionalConfigListVO();
            vo.setLabel(vmsRealRegionalConfig.getName());
            vo.setValue(vmsRealRegionalConfig.getName());
            vmsRealRegionalConfigs.add(vo);
        }

        List<VmsRealRegionalConfigListVO> collect = list.stream().map(item -> {
            VmsRealRegionalConfigListVO vo = new VmsRealRegionalConfigListVO();
            vo.setLabel(item.getName());
            vo.setValue(item.getName());
            vo.setChildren(map.get(item.getId()));
            return vo;
        }).collect(Collectors.toList());

        return Result.OK(collect);
    }

}
